(function (document, $, log) {
    $.fn.artZoom = function (config) {
        config = $.extend({}, $.fn.artZoom.defaults, config);

        var tmpl, viewport,
		$this = this,
		loadImg = {},
		path = config.path,
		loading = path + '/loading.gif',
		max = path + '/zoomin.cur',
		min = path + '/zoomout.cur';

        new Image().src = loading;

        max = 'url(\'' + max + '\'), pointer';
        min = 'url(\'' + min + '\'), pointer';

        tmpl = [
		'<div class="ui-artZoom-toolbar" style="display:block">',
			'<span class="ui-artZoom-buttons" style="display:block">',
				'<a href="#" data-go="left" class="ui-artZoom-left"><span></span>',
					config.left,
				'</a>',
				'<a href="#" data-go="right" class="ui-artZoom-right"><span></span>',
					config.right,
				'</a>',
				'<a href="#" data-go="source" class="ui-artZoom-source"><span></span>',
					config.source,
				'</a>',
				'<a href="#" data-go="hide" class="ui-artZoom-hide"><span></span>',
					config.hide,
				'</a>',
			'</span>',
			'<span class="ui-artZoom-loading">',
				'<img data-live="stop" src="',
					loading,
					'" style="',
					'display:inline-block;*zoom:1;*display:inline;vertical-align:middle;',
					'width:16px;height:16px;"',
				' />',
				' <span>Loading..</span>',
			'</span>',
		'</div>',
		'<div class="ui-artZoom-box" style="display:block">',
			'<span class="ui-artZoom-photo" data-go="hide"',
			' style="display:inline-block;*display:inline;*zoom:1;overflow:hidden;position:relative;cursor:',
				min,
			'">',
				'<img data-name="thumb" data-go="hide" data-live="stop" src="',
					loading,
				'" />',
			'</span>',
		'</div>'
	].join(''); 
        
        // jQuery事件代理
        this.live('click', function (event) {
            if (this.nodeName !== 'IMG' && this.getAttribute('data-live') === 'stop') return false;

            var $artZoom, buttonClick,
			that = this,
			$this = $(that),
			$parent = $this.parent(),
			src = that.src,
			show = $this.attr('data-artZoom-show') || src,
			source = $this.attr('data-artZoom-source') || show,
			maxWidth = config.maxWidth || ($parent[0].nodeName === 'A' ? $this.parent() : $this).parent().width(),
			maxHeight = config.maxHeight || 99999;

            maxWidth = maxWidth - config.borderWidth;

            // 对包含在链接内的图片进行特殊处理
            if ($parent[0].nodeName === 'A') {
                show = $parent.attr('data-artZoom-show') || $parent.attr('href');
                source = $parent.attr('data-artZoom-source') || $parent.attr('rel');
            };

            // 第一次点击
            if (!$this.data('artZoom')) {
                var wrap = document.createElement('div'),
				$thumb, $box, $show;

                $artZoom = $(wrap);
                wrap.className = 'ui-artZoom ui-artZoom-noLoad';
                wrap.innerHTML = tmpl;

                ($parent[0].nodeName === 'A' ? $this.parent() : $this).before(wrap);
                $this.data('artZoom', $artZoom);
                $box = $artZoom.find('.ui-artZoom-box');
                $thumb = $artZoom.find('[data-name=thumb]');

                // 快速获取大图尺寸
                imgReady(show, function () {
                    var width = this.width,
					height = this.height,
					maxWidth2 = Math.min(maxWidth, width);

                    height = maxWidth2 / width * height;
                    width = maxWidth2;

                    // 插入大图并使用逐渐清晰加载的效果
                    $thumb.attr('src', src).
					css(config.blur ? {
					    width: width + 'px',
					    height: height + 'px'
					} : { display: 'none' }).
					after([
					'<img class="ui-artZoom-show" title="',
						that.title,
						'" alt="',
						that.alt,
						'" src="',
						show,
						'" style="width:',
						width,
						'px;height:',
						height, // IE8 超长图片height属性失效BUG，改用CSS
						'px;position:absolute;left:0;top:0;background:transparent"',
					' />'
				].join(''));

                    $show = $artZoom.find('.ui-artZoom-show');
                    $thumb.attr('class', 'ui-artZoom-show');

                    $artZoom.addClass('ui-artZoom-ready');
                    $artZoom.find('.ui-artZoom-buttons').show();
                    $this.data('artZoom-ready', true);
                    $this.hide();
                    $box.show();

                    // 大图完全加载完毕
                }, function () {
                    $thumb.removeAttr('class').hide();
                    $show.css({
                        position: 'static',
                        left: 'auto',
                        top: 'auto'
                    });

                    $artZoom.removeClass('ui-artZoom-noLoad');
                    $artZoom.find('.ui-artZoom-loading').hide();
                    $this.data('artZoom-load', true);

                    // 图片加载错误
                }, function () {
                    $artZoom.addClass('ui-artZoom-error');
                    log('jQuery.fn.artZoom: Load "' + show + '" Error!');
                });

            } else {
                $this.hide();
            };

            $artZoom = $this.data('artZoom');
            buttonClick = function (event) {
                var target = this,
				go = target.getAttribute('data-go'),
				live = target.getAttribute('data-live'),
				degree = $this.data('artZoom-degree') || 0,
				elem = $artZoom.find('.ui-artZoom-show')[0];

                if (live === 'stop') return false;
                if (/img|canvas$/i.test(target.nodeName)) go = 'hide';

                switch (go) {
                    case 'left':
                        degree -= 90;
                        degree = degree === -90 ? 270 : degree;
                        break;
                    case 'right':
                        degree += 90;
                        degree = degree === 360 ? 0 : degree;
                        break;
                    case 'source':
                        window.open(source || show || src);
                        break;
                    case 'hide':
                        $this.show();
                        $artZoom.find('.ui-artZoom-toolbar').hide();
                        $artZoom.hide();
                        $artZoom.find('[data-go]').die('click', buttonClick);
                        break;
                };

                if ((go === 'left' || go === 'right') && $this.data('artZoom-load')) {
                    imgRotate(elem, degree, maxWidth, maxHeight);
                    $this.data('artZoom-degree', degree);
                };

                return false;
            };
            $artZoom.show().find('.ui-artZoom-toolbar').slideDown(150);
            $artZoom.find('[data-go]').live('click', buttonClick);

            return false;
        });


        // 给目标缩略图应用外部指针样式
        this.live('mouseover', function () {
            if (this.className !== 'ui-artZoom-show') this.style.cursor = max;
        });

        // 预加载指针形状图标
        if (this[0]) this[0].style.cursor = max;



        return this;
    };
    $.fn.artZoom.defaults = {
        path: './images',
        left: '\u5de6\u65cb\u8f6c',
        right: '\u53f3\u65cb\u8f6c',
        source: '\u770b\u539f\u56fe',
        hide: '\xd7',
        blur: true,
        preload: true,
        maxWidth: null,
        maxHeight: null,
        borderWidth: 18
    };

    /**
    * 图片旋转
    * @version	2011.05.27
    * @author	TangBin
    * @param	{HTMLElement}	图片元素
    * @param	{Number}		旋转角度 (可用值: 0, 90, 180, 270)
    * @param	{Number}		最大宽度限制
    * @param	{Number}		最大高度限制
    */
    var imgRotate = $.imgRotate = function () {
        var eCanvas = '{$canvas}',
		isCanvas = !!document.createElement('canvas').getContext;

        return function (elem, degree, maxWidth, maxHeight) {
            var x, y, getContext,
			resize = 1,
			width = elem.naturalWidth,
			height = elem.naturalHeight,
			canvas = elem[eCanvas];

            // 初次运行
            if (!elem[eCanvas]) {

                // 获取图像未应用样式的真实大小 (IE和Opera早期版本)
                if (!('naturalWidth' in elem)) {
                    var run = elem.runtimeStyle, w = run.width, h = run.height;
                    run.width = run.height = 'auto';
                    elem.naturalWidth = width = elem.width;
                    elem.naturalHeight = height = elem.height;
                    run.width = w;
                    run.height = h;
                };

                elem[eCanvas] = canvas = document.createElement(isCanvas ? 'canvas' : 'span');
                elem.parentNode.insertBefore(canvas, elem.nextSibling);
                elem.style.display = 'none';
                canvas.className = elem.className;
                canvas.title = elem.title;
                if (!isCanvas) {
                    canvas.img = document.createElement('img');
                    canvas.img.src = elem.src;
                    canvas.appendChild(canvas.img);
                    canvas.style.cssText = 'display:inline-block;*zoom:1;*display:inline;' +
                    // css reset
					'padding:0;margin:0;border:none 0;position:static;float:none;overflow:hidden;width:auto;height:auto';
                };
            };

            var size = function (isSwap) {
                if (isSwap) width = [height, height = width][0];
                if (width > maxWidth) {
                    resize = maxWidth / width;
                    height = resize * height;
                    width = maxWidth;
                };
                if (height > maxHeight) {
                    resize = resize * maxHeight / height;
                    width = maxHeight / height * width;
                    height = maxHeight;
                };
                if (isCanvas) (isSwap ? height : width) / elem.naturalWidth;
            };

            switch (degree) {
                case 0:
                    x = 0;
                    y = 0;
                    size();
                    break;
                case 90:
                    x = 0;
                    y = -elem.naturalHeight;
                    size(true);
                    break;
                case 180:
                    x = -elem.naturalWidth;
                    y = -elem.naturalHeight
                    size();
                    break;
                case 270:
                    x = -elem.naturalWidth;
                    y = 0;
                    size(true);
                    break;
            };

            if (isCanvas) {
                canvas.setAttribute('width', width);
                canvas.setAttribute('height', height);
                getContext = canvas.getContext('2d');
                getContext.rotate(degree * Math.PI / 180);
                getContext.scale(resize, resize);
                getContext.drawImage(elem, x, y);
            } else {
                canvas.style.width = width + 'px';
                canvas.style.height = height + 'px'; // 解决IE8使用滤镜后高度不能自适应
                canvas.img.style.filter = 'progid:DXImageTransform.Microsoft.BasicImage(rotation=' + degree / 90 + ')';
                canvas.img.width = elem.width * resize;
                canvas.img.height = elem.height * resize;
            };
        };
    } ();

    /**
    * 图片头数据加载就绪事件 - 更快获取图片尺寸
    * @version	2011.05.27
    * @author	TangBin
    * @see		http://www.planeart.cn/?p=1121
    * @param	{String}	图片路径
    * @param	{Function}	尺寸就绪
    * @param	{Function}	加载完毕 (可选)
    * @param	{Function}	加载错误 (可选)
    * @example imgReady('http://www.google.com.hk/intl/zh-CN/images/logo_cn.png', function () {
    alert('size ready: width=' + this.width + '; height=' + this.height);
    });
    */
    var imgReady = (function () {
        var list = [], intervalId = null,

        // 用来执行队列
	tick = function () {
	    var i = 0;
	    for (; i < list.length; i++) {
	        list[i].end ? list.splice(i--, 1) : list[i]();
	    };
	    !list.length && stop();
	},

        // 停止所有定时器队列
	stop = function () {
	    clearInterval(intervalId);
	    intervalId = null;
	};

        return function (url, ready, load, error) {
            var onready, width, height, newWidth, newHeight,
			img = new Image();

            img.src = url;

            // 如果图片被缓存，则直接返回缓存数据
            if (img.complete) {
                ready.call(img);
                load && load.call(img);
                return;
            };

            width = img.width;
            height = img.height;

            // 加载错误后的事件
            img.onerror = function () {
                error && error.call(img);
                onready.end = true;
                img = img.onload = img.onerror = null;
            };

            // 图片尺寸就绪
            onready = function () {
                newWidth = img.width;
                newHeight = img.height;
                if (newWidth !== width || newHeight !== height ||
                // 如果图片已经在其他地方加载可使用面积检测
				newWidth * newHeight > 1024
			) {
                    ready.call(img);
                    onready.end = true;
                };
            };
            onready();

            // 完全加载完毕的事件
            img.onload = function () {
                // onload在定时器时间差范围内可能比onready快
                // 这里进行检查并保证onready优先执行
                !onready.end && onready();

                load && load.call(img);

                // IE gif动画会循环执行onload，置空onload即可
                img = img.onload = img.onerror = null;
            };

            // 加入队列中定期执行
            if (!onready.end) {
                list.push(onready);
                // 无论何时只允许出现一个定时器，减少浏览器性能损耗
                if (intervalId === null) intervalId = setInterval(tick, 40);
            };
        };
    })();

} (document, jQuery, function (msg) { window.console && console.log(msg) }));
